
#include "CFunc.h"

// C编译器不支持 bool,false,true,nullptr,wchar_t等关键字

int MemCmpX(const void* pStr1, const void* pStr2, int nLen)
{
	for (int i = 0; i < nLen; ++i)
	{
		if (((unsigned char*)pStr1)[i] > ((unsigned char*)pStr2)[i])
		{
			return 1;
		}
		else if (((unsigned char*)pStr1)[i] < ((unsigned char*)pStr2)[i])
		{
			return -1;
		}
	}
	return 0;
}

void* MemStrX(void* pBuf, const void* pStr, int nBuf, int nStr)
{
	for (int i = 0; i <= nBuf-nStr; ++i)
	{
		int j = 0;
		for (;j < nStr; ++j)
		{
			if (((char*)pBuf)[i+j] != ((char*)pStr)[j])
				break;
		}
		if (j == nStr) return &(((char*)pBuf)[i]);
	}

	return (void*)0;
}

void MemZeroX(void *pMem, int nLen)
{
#ifdef __X2LIB_WIN32__
	__asm{nop}
#endif
	for (int i = nLen - 1; i >= 0; --i)
	{
		((char*)pMem)[i] = 0;
	}
}

void MemCpyX(void *pOut, const void *pIn, int nLen)
{
#ifdef __X2LIB_WIN32__
	__asm {nop} // 防止当前函数被编译为memcpy
#endif
	//if (iCpy == 0)
	{
		for (int i = 0; i < nLen; i++)
		{
			((char*)pOut)[i] = ((char*)pIn)[i];
		}
	}
	//else
	//{
	//	for (int i = nLen - 1; i >= 0; --i)
	//		((char*)pOut)[i] = ((char*)pIn)[i];
	//}
}

int StrLenX(const void *pStr, int chars)
{
	// wchar_t in linux/unix sometimes is 2 or 4 bytes, in windows, offen 2 bytes
	if(!pStr) return 0;
	char *p = (char*)pStr;
	char temp[8] = { 0 };

	while (1)
	{
		if (MemCmpX(p, temp, chars) == 0)
		{
			return (p - (char*)pStr) / chars;
		}
		p+=chars;
	}
	return -1;
}

char* StrCatX(char *pDst, const char *pSrc)
{
	char *p = pDst;
	while (*p)++p;
	do
	{
		*p++ = *pSrc;
	} while (*pSrc++);
	return pDst;
}


int CmdToArgv(const char *pCmd, char *pArgs[])
{
	char*  _argv;
	unsigned long   len;
	unsigned long   argc;
	char   a;
	unsigned long   i, j;

	int  in_QM;
	int  in_TEXT;
	int  in_SPACE;

	len = StrLenX(pCmd, 1);
	i = ((len + 2) / 2)*sizeof(void*) + sizeof(void*);

	_argv = (char*)(((unsigned char*)pArgs) + i);

	argc = 0;
	pArgs[argc] = _argv;
	in_QM = 0;
	in_TEXT = 0;
	in_SPACE = 1;
	i = 0;
	j = 0;

	while (a = pCmd[i]) {
		if (in_QM) {
			if (a == '\"') {
				in_QM = 0;
			}
			else {
				_argv[j] = a;
				j++;
			}
		}
		else {
			switch (a) {
			case '\"':
				in_QM = 1;
				in_TEXT = 1;
				if (in_SPACE) {
					pArgs[argc] = _argv + j;
					argc++;
				}
				in_SPACE = 0;
				break;
			case ' ':
			case '\t':
			case '\n':
			case '\r':
				if (in_TEXT) {
					_argv[j] = '\0';
					j++;
				}
				in_TEXT = 0;
				in_SPACE = 1;
				break;
			default:
				in_TEXT = 1;
				if (in_SPACE) {
					pArgs[argc] = _argv + j;
					argc++;
				}
				_argv[j] = a;
				j++;
				in_SPACE = 0;
				break;
			}
		}
		i++;
	}
	_argv[j] = '\0';
	pArgs[argc] = 0;
	return argc;
}

